package cn.xchats.rpc.client.load;

import cn.xchats.rpc.common.dto.RequestDto;
import cn.xchats.rpc.common.util.PropertyUtil;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/*
 *
 *@author teddy
 *@date 2018/7/6
 */
@Component
public class SelectHandler {

    @LoadBalance
    private static LoadBalanceConfig loadBalanceConfig;

    private static String loadBalanceClass;
    private static final String defaultLoadBalanceClass = "cn.xchats.rpc.client.load.RoundrobinLoadBalance";
    public static final int failure = -1;

    public static final Map<String, Map<String, String>> cacheNode = new HashMap<>(); //缓存的服务节点  key: ip+端口  value: 单个节点   path：value

    public SelectHandler() {
        try {
            loadBalanceClass = PropertyUtil.getProperty("rpc.loadbalance.class");
            if (null == loadBalanceClass) {
                loadBalanceClass = defaultLoadBalanceClass;
            }
            Class<?> beanClass = Class.forName(loadBalanceClass);
            Object bean = beanClass.newInstance();
            if (bean instanceof LoadBalanceConfig)
                loadBalanceConfig = ((LoadBalanceConfig) bean);
            else
                throw new NullPointerException("init error : rpc.loadbalance.class is not find");

            System.out.println("负载  > > > > > > > > > > > > " + beanClass.getTypeName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int failoverSelect(RequestDto request) {
        //当前调用的服务已宕机
        int failoverSize = LoadBalanceConfig.serverAddressList.size();
        int select = select(request);
        if (failure != select)
            return select;

        for (int i = 0; i < failoverSize; i++) {
            int failoverSelect = select(request);
            if (failure != failoverSelect)
                return failoverSelect;
        }
        //全部宕机
        return failure;
    }

    private static int select(RequestDto request) {
        int select = loadBalanceConfig.select();
        Map<String, Map<String, String>> cacheNode = SelectHandler.cacheNode;

        //校验当前选择的服务是否宕机
        String serverAddress = LoadBalanceConfig.serverAddressList.get(select);
        Map<String, String> cacheNodeMap = cacheNode.get(serverAddress);
        if (cacheNodeMap.containsKey(request.getMethod()))
            return select;
        else
            return failure;
    }
}
